using System;
using System.Windows.Forms;
using CSW.Framework.Common;
using CSW.Framework.UI.Binding;
using DevExpress.XtraEditors;

namespace CSW.Framework.UI.DevEx.Binding
{
    /// <summary>
    /// A wrapper class for binding <see cref="MemoEdit"/> objects with <see cref="Binder"/>.
    /// </summary>
    public class BindableMemoEdit : IBindableControl
    {
        private readonly MemoEdit m_MemoEdit;
        private readonly bool m_ValidateOnChanged;

        /// <summary>
        /// Initializes a new instance of the <see cref="BindableMemoEdit"/> class.
        /// </summary>
        /// <param name="memoEdit">The <see cref="MemoEdit"/> control to wrap.</param>
        public BindableMemoEdit(MemoEdit memoEdit)
            : this(memoEdit, false)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BindableMemoEdit"/> class.
        /// </summary>
        /// <param name="memoEdit">The <see cref="MemoEdit"/> control to wrap.</param>
        /// <param name="validateOnChanged">if set to <c>true</c> [validate on changed].</param>
        public BindableMemoEdit(MemoEdit memoEdit, bool validateOnChanged)
        {
            Guard.ArgumentNotNull(memoEdit, "memoEdit");

            m_MemoEdit = memoEdit;
            m_ValidateOnChanged = validateOnChanged;

            m_MemoEdit.Validated += MemoEdit_Validated;

            if (validateOnChanged)
                m_MemoEdit.TextChanged += MemoEdit_Validated;
        }

        private void MemoEdit_Validated(object sender, EventArgs e)
        {
            EventHandler tmpValidated = Validated;
            if (tmpValidated != null)
            {
                tmpValidated(sender, e);
            }
        }

        #region IBindableControl Members

        /// <summary>
        /// Occurs when the control has validated.
        /// </summary>
        public event EventHandler Validated;

        /// <summary>
        /// Sends the <see cref="Validated"/> event.
        /// </summary>
        public void SendValidated()
        {
            EventHandler validated = Validated;
            if (validated != null)
                validated(this, EventArgs.Empty);
        }

        /// <summary>
        /// Gets the control this object wraps.
        /// </summary>
        /// <value>The control this object wraps.</value>
        public Control Control
        {
            get { return m_MemoEdit; }
        }

        /// <summary>
        /// Gets or sets the value of the control.
        /// </summary>
        /// <value>The value of the control.</value>
        public object Value
        {
            get { return m_MemoEdit.Text; }
            set
            {
                object newValue = value ?? string.Empty;
                if (!m_MemoEdit.Text.Equals(newValue))
                {
                    m_MemoEdit.Text = newValue.ToString();
                }
            }
        }

        /// <summary>
        /// Gets the name of the control.
        /// </summary>
        /// <value>The name of the control.</value>
        public string Name
        {
            get { return m_MemoEdit.Name; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the control is enabled.
        /// </summary>
        /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
        public bool Enabled
        {
            get { return m_MemoEdit.Enabled; }
            set { m_MemoEdit.Enabled = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the control is read only.
        /// </summary>
        /// <value><c>true</c> if read only; otherwise, <c>false</c>.</value>
        public bool ReadOnly
        {
            get { return m_MemoEdit.Properties.ReadOnly; }
            set 
            { 
                m_MemoEdit.Properties.ReadOnly = value;
                m_MemoEdit.TabStop = !value;
            }
        }

        /// <summary>
        /// Focuses the control.
        /// </summary>
        public void Focus()
        {
            m_MemoEdit.Focus();
        }

        /// <summary>
        /// Gets the tab index.
        /// </summary>
        /// <value>The tab index.</value>
        public int TabIndex
        {
            get { return m_MemoEdit.TabIndex; }
        }

        /// <summary>
        /// Gets or sets the maximum string length.
        /// </summary>
        /// <value>The maximum string length.</value>
        public int MaxLength
        {
            get { return m_MemoEdit.Properties.MaxLength; }
            set { m_MemoEdit.Properties.MaxLength = value; }
        }

        #endregion

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Validated = null;

            m_MemoEdit.Validated -= MemoEdit_Validated;

            if (m_ValidateOnChanged)
                m_MemoEdit.TextChanged -= MemoEdit_Validated;
        }
    }
}